import BaseUtil from '@/BaseUtil';
import PlayerUtil from '@/PlayerUtil';
import RandomUtil from '@/RandomUtil';
import TextTagUtil from '@/TextTagUtil';
import UnitItemEvent from '@/event/UnitItemEvent';
import { OrderId } from '@/globals/order';
import { Trigger } from '@/trigger';
import { gameTips } from './config';
import ItemUtil from '@/ItemUtil';
import ArrayUtil from '@/ArrayUtil';
import MathUtil from '@/MathUtil';
import { RuinIds } from '../Ruins/config';
import InputUtil from '@/InputUtil';
import FrameTipUtil from 'code/UI/common/FrameTipUtil';
import BooleanCommon from 'code/Core/Common/BooleanCommon';
import MovementCommon from 'code/Core/Common/MovementCommon';

// '光明' | '黑暗' | '火焰' | '冰霜' | '剧毒' | '风系' | '闪电' | '土系' | '奥术'
const colors: { [key: string]: { r: number; g: number; b: number } } = {
    light: { r: 217, g: 217, b: 25 },
    fire: { r: 254, g: 138, b: 14 },
    dark: { r: 182, g: 5, b: 138 },
    ice: { r: 126, g: 191, b: 241 },
    poision: { r: 32, g: 192, b: 0 },
    wind: { r: 238, g: 238, b: 51 },
    lighting: { r: 0, g: 66, b: 255 },
    earth: { r: 227, g: 83, b: 0 },
    arcane: { r: 229, g: 91, b: 176 },
    physical: { r: 221, g: 51, b: 0 },
};

export default class GameCommon {
    constructor() {
        se.onUnitPickupItem(this.自动合并可充物品);
        BaseUtil.onTimer(10, this.复活树木);
        this.jumpSys();
        this.显示伤害();
        // 游戏技巧提示
        this.showGameTips();
        // 满格拾取
        this.fullInventoryPickupItem();
    }
    fullInventoryPickupItem() {
        let t = new Trigger();
        t.registerAnyUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER);
        t.addAction(GameCommon.proccessPickItem);
    }
    static itemCanPickPool: item[] = [];
    static proccessPickItem(this: void) {
        let order = GetIssuedOrderId();
        let item = GetOrderTargetItem();
        if (item == null) return;
        if (RuinIds.includes(id2string(GetItemTypeId(item)))) return;
        if (order != OrderId.Smart) return;
        let u = GetTriggerUnit();
        let x = GetItemX(item),
            y = GetItemY(item);
        let dis = MathUtil.distanceBetweenPoints(GetUnitX(u), GetUnitY(u), x, y);
        if (dis > 350) {
            // let tar = GetOrderTargetUnit();
            // if (tar != null) {
            //     IssueTargetOrderById(u, OrderId.Smart, tar);
            // }else{
            //     IssuePointOrderById(u, OrderId.Move, x, y);
            // }
            return;
        }
        if (ItemUtil.getAllItemFromUnit(GetTriggerUnit()).length != 6) return;
        let p = GetOwningPlayer(u);
        if (UIManager.UIBakpack.model.isInventoryFull(p)) return;
        if (GameCommon.itemCanPickPool.includes(item)) return;
        GameCommon.itemCanPickPool.push(item);
        UIManager.UIBakpack.model.addItem(item, p);
        BaseUtil.runLater(0.5, () => {
            if (GameCommon.itemCanPickPool.includes(item)) {
                ArrayUtil.removeElement(GameCommon.itemCanPickPool, item);
            }
        });
        if (p == GetLocalPlayer()) {
            FrameTipUtil.showIconMoveIntoAnimation(EXGetItemDataString(GetItemTypeId(item), 1), InputUtil.getMouseSceneX(), InputUtil.getMouseSceneY(), 0.053, 0.17, 0.5, 0.025, 0.015);
        }
    }
    showGameTips() {
        let t = RandomUtil.nextInt(20, 40);
        BaseUtil.runLater(t, () => {
            let i = RandomUtil.nextInt(0, gameTips.length - 1);
            PlayerUtil.message(gameTips[i]);
            this.showGameTips();
        });
    }
    // static damageCache: Map<unit, number> = new Map();
    显示伤害() {
        EventManager.onTakeDamage((d) => {
            if (d.lastDamage < 1) return;
            if (d.hasDogged) {
                TextTagUtil.text('未命中', d.target, 8, 1.5);
            } else if (d.isPhysical) {
                if (d.isAttack || d.isAttach) {
                    TextTagUtil.text('-' + I2S(R2I(d.lastDamage)), d.target, 8, 1.5);
                } else {
                    TextTagUtil.text('-' + I2S(R2I(d.lastDamage)), d.target, 8, 1.5, colors['physical'].r, colors['physical'].g, colors['physical'].b);
                }
            } else if (d.magicType) {
                TextTagUtil.text('-' + I2S(R2I(d.lastDamage)), d.target, 8, 1.5, colors[d.magicType].r, colors[d.magicType].g, colors[d.magicType].b);
            }
        });
        EventManager.受到治疗((d) => {
            TextTagUtil.text('+' + I2S(R2I(d.lastDamage)), d.target, 8, 1.5, 100, 255, 0);
        });
    }
    自动合并可充物品(this: void, d: UnitItemEvent) {
        if (GetItemType(d.manipulatedItem) != ITEM_TYPE_CHARGED) return;
        let id = GetItemTypeId(d.manipulatedItem);
        for (let i = 0; i < 6; i++) {
            let item = UnitItemInSlot(d.trigUnit, i);
            if (GetItemTypeId(item) == id && item != d.manipulatedItem) {
                let charges = GetItemCharges(d.manipulatedItem);
                SetItemCharges(item, charges + GetItemCharges(item));
                RemoveItem(d.manipulatedItem);
            }
        }
    }
    stopAllyAttack() {
        se.onUnitAttacked((e) => {
            if (BooleanCommon.isPlayerUnit(e.attacker) && IsUnitAlly(e.trigUnit, GetOwningPlayer(e.attacker))) {
                IssueImmediateOrder(e.attacker, 'stop');
            }
        });
    }
    复活树木() {
        EnumDestructablesInRectAll(GetWorldBounds(), GameCommon.reviveDestructable);
        return true;
    }
    static reviveDestructable(this: void) {
        let d = GetEnumDestructable();
        if (IsDestructableDeadBJ(d)) DestructableRestoreLife(d, 100, true);
    }
    static jumpPool: unit[] = [];
    jumpSys() {
        let t1 = new Trigger();
        t1.registerEnterRect(gg_rct_jump_up_n);
        t1.registerEnterRect(gg_rct_jump_down_n);
        t1.addAction(GameCommon.jumpDownAction);
        let t2 = new Trigger();
        t2.registerEnterRect(gg_rct_jump_up_s);
        t2.registerEnterRect(gg_rct_jump_down_s);
        t2.addAction(GameCommon.jumpUpAction);
    }
    static jumpUpAction(this: void) {
        let u = GetTriggerUnit();
        if (IsUnitEnemy(u, Player(0))) return;
        if (GameCommon.jumpPool.includes(u)) return;
        GameCommon.jumpPool.push(u);
        IssueImmediateOrderById(u, OrderId.Stop);
        MovementCommon.hitFly({
            target: u,
            angle: 90,
            speed: 600,
            distance: 300,
            maxHeight: 250,
            caster: u,
        });
        BaseUtil.runLater(0.6, () => {
            ArrayUtil.removeElement(GameCommon.jumpPool, u);
        });
    }
    static jumpDownAction(this: void) {
        let u = GetTriggerUnit();
        if (IsUnitEnemy(u, Player(0))) return;
        if (GameCommon.jumpPool.includes(u)) return;
        GameCommon.jumpPool.push(u);
        IssueImmediateOrderById(u, OrderId.Stop);
        MovementCommon.hitFly({
            target: u,
            angle: -90,
            speed: 600,
            distance: 300,
            maxHeight: 250,
            caster: u,
        });
        BaseUtil.runLater(0.6, () => {
            ArrayUtil.removeElement(GameCommon.jumpPool, u);
        });
    }
}
